package cn.easyplatform.studio.web.views.impl;

import cn.easyplatform.entities.beans.project.ProjectBean;
import cn.easyplatform.entities.beans.table.TableBean;
import cn.easyplatform.lang.Strings;
import cn.easyplatform.studio.StudioApp;
import cn.easyplatform.studio.cmd.entity.QueryModelCmd;
import cn.easyplatform.studio.cmd.entity.ScanCmd;
import cn.easyplatform.studio.context.Contexts;
import cn.easyplatform.studio.vos.EntityVo;
import cn.easyplatform.studio.vos.ScanVo;
import cn.easyplatform.studio.vos.TableVo;
import cn.easyplatform.studio.web.editors.EditorCallback;
import cn.easyplatform.type.EntityType;
import org.zkoss.util.resource.Labels;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.event.Event;
import org.zkoss.zk.ui.event.Events;
import org.zkoss.zk.ui.event.OpenEvent;
import org.zkoss.zk.ui.util.Clients;
import org.zkoss.zul.*;
import org.zkoss.zul.event.PagingEvent;
import org.zkoss.zul.event.ZulEvents;

import java.util.ArrayList;
import java.util.List;

public class TableExportView extends AbstractView<List<TableBean>> {
    private Vlayout vlayout;
    private Bandbox searchbox;
    private Listbox sourcesBox;
    private Listbox targetsBox;
    private List<TableVo> allData;
    private Paging paging;
    private Combobox datasource;
    /**
     * @param cb
     */
    protected TableExportView(EditorCallback<List<TableBean>> cb, Component component) {
        super(component, cb);
    }

    @Override
    protected void createContent(Component parent) {

        vlayout = new Vlayout();
        vlayout.setVflex("1");

        Hlayout topHlayout = new Hlayout();
        topHlayout.setHflex("1");

        Image image = new Image();
        image.setSrc("~./images/db.gif");
        image.setStyle("margin-top:3px");
        image.setParent(topHlayout);
        Div div = new Div();
        div.setStyle("margin-top:3px");
        div.setParent(topHlayout);
        Label label1 = new Label(Labels.getLabel("entity.table.db")+":");
        label1.setParent(div);

        datasource = new Combobox();
        datasource.setId("tableExportView_combobox_datasource");
        List<EntityVo> ds = StudioApp.execute(new QueryModelCmd(
                EntityType.DATASOURCE.getName()));
        ProjectBean pb = Contexts.getProject();
        for (EntityVo vo : ds) {
            Comboitem ci = new Comboitem(vo.getId());
            ci.setDescription(vo.getName());
            datasource.appendChild(ci);
            if (pb.getBizDb().equals(vo.getId()))
                datasource.setSelectedItem(ci);
        }
        datasource.addEventListener(Events.ON_CHANGE, this);
        datasource.setParent(topHlayout);

        searchbox = new Bandbox();
        searchbox.setId("tableExportView_bandbox_search");
        searchbox.setPlaceholder(Labels.getLabel("navi.search.placeholder"));
        searchbox.addEventListener(Events.ON_OK, this);
        searchbox.addEventListener(Events.ON_CHANGE, this);
        searchbox.addEventListener(Events.ON_OPEN, this);
        searchbox.setParent(topHlayout);

        topHlayout.setParent(vlayout);

        Hlayout centerHlayout = new Hlayout();
        centerHlayout.setHflex("1");
        centerHlayout.setVflex("1");
        centerHlayout.setStyle("padding-top:3px");

        Vlayout leftLayout = new Vlayout();
        leftLayout.setHflex("1");
        leftLayout.setVflex("1");
        leftLayout.setParent(centerHlayout);
        sourcesBox = new Listbox();
        sourcesBox.setId("tableExportView_listbox_sources");
        sourcesBox.setHflex("1");
        sourcesBox.setVflex("1");
        sourcesBox.setCheckmark(true);
        sourcesBox.setMultiple(true);
        sourcesBox.setMold("paging");
        sourcesBox.setPageSize(20);
        sourcesBox.setParent(leftLayout);

        paging = new Paging();
        paging.setPageSize(20);
        paging.setDetailed(true);
        paging.addEventListener(ZulEvents.ON_PAGING, this);
        paging.setParent(leftLayout);

        Listhead listhead = new Listhead();
        listhead.setSizable(true);
        listhead.setParent(sourcesBox);

        Listheader idListheader = new Listheader();
        idListheader.setLabel(Labels.getLabel("entity.name"));
        idListheader.setWidth("200px");
        idListheader.setParent(listhead);

        Listheader nameListheader = new Listheader();
        nameListheader.setLabel(Labels.getLabel("entity.desp"));
        nameListheader.setWidth("200px");
        nameListheader.setParent(listhead);

        Vlayout middleLayout = new Vlayout();
        middleLayout.setSpacing("10px");
        middleLayout.setWidth("24px");
        middleLayout.setParent(centerHlayout);

        Image createAllImg = new Image();
        createAllImg.setId("tableExportView_image_createAll");
        createAllImg.setSrc("~./images/rightrightarrow_g.png");
        createAllImg.setStyle("cursor:pointer");
        createAllImg.setTooltip(Labels.getLabel("button.createAll"));
        createAllImg.setParent(middleLayout);
        createAllImg.addEventListener(Events.ON_CLICK, this);

        Image createImg = new Image();
        createImg.setId("tableExportView_image_create");
        createImg.setSrc("~./images/rightarrow_g.png");
        createImg.setStyle("cursor:pointer");
        createImg.setTooltip(Labels.getLabel("button.create"));
        createImg.setParent(middleLayout);
        createImg.addEventListener(Events.ON_CLICK, this);

        Image removeImg = new Image();
        removeImg.setId("tableExportView_image_remove");
        removeImg.setSrc("~./images/leftarrow_g.png");
        removeImg.setStyle("cursor:pointer");
        removeImg.setTooltip(Labels.getLabel("button.remove"));
        removeImg.setParent(middleLayout);
        removeImg.addEventListener(Events.ON_CLICK, this);

        Image removeAllImg = new Image();
        removeAllImg.setId("tableExportView_image_removeAll");
        removeAllImg.setSrc("~./images/leftleftarrow_g.png");
        removeAllImg.setStyle("cursor:pointer");
        removeAllImg.setTooltip(Labels.getLabel("button.removeAll"));
        removeAllImg.setParent(middleLayout);
        removeAllImg.addEventListener(Events.ON_CLICK, this);

        middleLayout.setParent(centerHlayout);

        targetsBox = new Listbox();
        targetsBox.setId("tableExportView_listbox_targets");
        targetsBox.setHflex("1");
        targetsBox.setVflex("1");
        targetsBox.setCheckmark(true);
        targetsBox.setMultiple(true);
        targetsBox.setMold("paging");
        targetsBox.setPageSize(20);
        targetsBox.setParent(centerHlayout);
        Listhead newListhead = (Listhead) listhead.clone();
        newListhead.setParent(targetsBox);

        centerHlayout.setParent(vlayout);
        vlayout.setParent(parent);

        Hlayout bottomHlayout = new Hlayout();
        bottomHlayout.setHflex("1");
        bottomHlayout.setHeight("38px");
        bottomHlayout.setParent(vlayout);
        Div d = new Div();
        d.setHflex("1");
        bottomHlayout.appendChild(d);

        Button btn = new Button(Labels.getLabel("button.ok"));
        btn.setId("tableExportView_image_chooseBtn");
        btn.setSclass("pull-right");
        btn.setStyle("margin-top: 8px;");
        btn.setIconSclass("z-icon-check");
        btn.addEventListener(Events.ON_CLICK, this);
        btn.setParent(bottomHlayout);

        sourcesBox.addEventListener("onLater", this);
        Clients.showBusy(Labels.getLabel("message.long.operation"));
        Events.echoEvent("onLater", sourcesBox, null);
    }
    @Override
    public void onEvent(Event event) throws Exception {
        if (event.getName().equals("onLater")) {
            try {
                if (event.getData() == null
                        || event.getData() instanceof String) {
                    ScanVo cv = StudioApp.execute(new ScanCmd(datasource
                            .getSelectedItem().getLabel(),
                            event.getData() == null ? paging.getPageSize() : 0,
                            1, searchbox.getValue(), true));
                    if (event.getData() == null)
                        paging.setTotalSize(cv.getTotalSize());
                    else
                        paging.setTotalSize(0);
                    createList(cv);
                } else if (event.getData() instanceof PagingEvent) {
                    PagingEvent pe = (PagingEvent) event.getData();
                    ScanVo cv = StudioApp.execute(new ScanCmd(datasource
                            .getSelectedItem().getLabel(),
                            paging.getPageSize(), pe.getActivePage() + 1,
                            searchbox.getValue(), false));
                    createList(cv);
                }
            } finally {
                Clients.clearBusy();
            }
        }

        Component c = event.getTarget();
        if (c == datasource || c == searchbox) {
            if (c == datasource)
                searchbox.setValue("");
            else if (event instanceof OpenEvent) {
                OpenEvent evt = (OpenEvent) event;
                searchbox.setRawValue(evt.getValue());
            }
            paging.setActivePage(0);
            Clients.showBusy(Labels.getLabel("message.long.operation"));
            Events.echoEvent("onLater", sourcesBox, null);
        }


        if (event.getTarget().getId().equals("tableExportView_image_createAll"))
            select(false);
        else if (event.getTarget().getId().equals("tableExportView_image_create"))
            select(true);
        else if (event.getTarget().getId().equals("tableExportView_image_remove"))
            unselect(true);
        else if (event.getTarget().getId().equals("tableExportView_image_removeAll"))
            unselect(false);
        else if (event.getTarget().getId().equals("tableExportView_image_chooseBtn"))
            choose();
        else if (event.getName().equals(ZulEvents.ON_PAGING)) {
            Clients.showBusy(Labels.getLabel("message.long.operation"));
            Events.echoEvent("onLater", sourcesBox, event);
        }
    }

    private void createList(ScanVo sv) {
        sourcesBox.getItems().clear();
        for (TableVo vo: sv.getSourceNew()) {
            Listitem li = new Listitem();
            li.setValue(vo);
            li.appendChild(new Listcell(vo.getId()));
            li.appendChild(new Listcell(vo.getName()));
            sourcesBox.appendChild(li);
        }
        for (TableVo vo: sv.getData()) {
            Listitem li = new Listitem();
            li.setValue(vo);
            li.appendChild(new Listcell(vo.getId()));
            li.appendChild(new Listcell(vo.getName()));
            sourcesBox.appendChild(li);
        }
    }

    private void select(boolean selectFlag) {
        for (Listitem sel : sourcesBox.getItems()) {
            if (selectFlag && !sel.isSelected())
                continue;
            if (sel.getValue() != null) {
                boolean exists = false;
                TableVo s = sel.getValue();
                for (Listitem li : targetsBox.getItems()) {
                    TableVo t = li.getValue();
                    if (s.getId().equals(t.getId())) {
                        exists = true;
                        break;
                    }
                }
                if (!exists) {
                    Listitem li = new Listitem();
                    li.appendChild(new Listcell(s.getId()));
                    li.appendChild(new Listcell(s.getName()));
                    li.setValue(s);
                    targetsBox.appendChild(li);
                }
            }
        }
    }

    private void unselect(boolean selectedFlag) {
        if (selectedFlag) {
            if (targetsBox.getSelectedCount() > 0) {
                List<Listitem> items = new ArrayList<Listitem>();
                for (Listitem li : targetsBox.getSelectedItems())
                    items.add(li);
                for (Listitem li : items)
                    li.detach();
            }
        } else
            targetsBox.getItems().clear();
    }

    private void choose() {
        List<TableBean> dicVos = new ArrayList<>();
        if (targetsBox.getItems() != null && targetsBox.getItems().size() > 0) {
            for (Listitem li : targetsBox.getItems()) {
                TableVo e = li.getValue();
                dicVos.add(e.getSource());
            }
        }
        if (cb != null)
            cb.setValue(dicVos);
        vlayout.getRoot().detach();
        onCloseClick(win);
    }

    private List<TableVo> search(String searchStr) {
        if (Strings.isBlank(searchStr))
            return allData;
        else {
            List<TableVo> data = new ArrayList<>();
            for (TableVo tableVo: allData) {
                if (tableVo.getId().contains(searchStr))
                    data.add(tableVo);
                else if (tableVo.getName().contains(searchStr))
                    data.add(tableVo);
            }
            return data;
        }
    }
}
